﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Input;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using ProtoImaginer.ProtoControl;

namespace ProtoImaginer.ProtoPage
{
    public partial class PageView : PhoneApplicationPage
    {
        //pinch related global variable
        private Point _oldFinger1, _oldFinger2;
        private double _initialScale;

        private ApplicationBarIconButton addControlButton;
        private ApplicationBarIconButton editTitleButton;
        private ApplicationBarIconButton delControlButton;
        private ApplicationBarIconButton linkPageButton;

        private List<ControlAtom> controls;
        private ControlAtom highlighted;

        public PageView()
        {
            InitializeComponent();
            controls = new List<ControlAtom>();
            addControlButton = (ApplicationBarIconButton)ApplicationBar.Buttons[0];
            editTitleButton = (ApplicationBarIconButton)ApplicationBar.Buttons[1];
            delControlButton = (ApplicationBarIconButton)ApplicationBar.Buttons[2];
            linkPageButton = (ApplicationBarIconButton)ApplicationBar.Buttons[3];

            AddControl();
            _initialScale = 1;

        }

        /*=====================================================================
         * Application bar
         *===================================================================*/

        private void AddControlButtonClick(object sender, EventArgs e)
        {
            AddControl();
        }
        private void EditTitleButtonClick(object sender, EventArgs e)
        {
            PivotPage.Title = "title updated";
            MessageBox.Show("edit title button clicked.");
        }
        private void DelControlButtonClick(object sender, EventArgs e)
        {
            //TBC
            DelControl();
        }



        private void LinkPageButtonClick(object sender, EventArgs e)
        {
            //TBC
        }
        /*=====================================================================
         * Gestures on Canvas, pinch session.
         *===================================================================*/

        private void CanvasPinchStarted(object sender, PinchStartedGestureEventArgs e)
        {
            _oldFinger1 = e.GetPosition(Canvas, 0);
            _oldFinger2 = e.GetPosition(Canvas, 1);

            DisablePivotPage();
        }

        private void CanvasPinchDelta(object sender, PinchGestureEventArgs e)
        {
            // update scaling
            Point pointA = e.GetPosition(Canvas, 0);
            Point pointB = e.GetPosition(Canvas, 1);

            CanvasTransformation.CenterX = (pointA.X + pointB.X) / 2;
            CanvasTransformation.CenterY = (pointA.Y + pointB.Y) / 2;

            //privent over zoom in /out
            //if (_initialScale < 2 && e.DistanceRatio < 1 || _initialScale > 0.5 && e.DistanceRatio > 1)
            _initialScale = CanvasTransformation.ScaleY = CanvasTransformation.ScaleX = _initialScale * e.DistanceRatio;
        }

        private void CanvasPinchCompleted(object sender, PinchGestureEventArgs e)
        {
            EnablePivotPage();
        }


        /*=====================================================================
         * Gestures on Canvas, drag session.
         *===================================================================*/

        //disable pivot's drag event.
        private void CanvasDragStarted(object sender, DragStartedGestureEventArgs e)
        {
            if (!e.Handled)
            {
                e.Handled = true;
                DisablePivotPage();
            }
        }

        //drag canvas around.
        private void CanvasDragDelta(object sender, DragDeltaGestureEventArgs e)
        {
            if (!e.Handled)
            {
                e.Handled = true;

                Canvas.Margin = new Thickness(
                        Canvas.Margin.Left + e.HorizontalChange,
                        Canvas.Margin.Top + e.VerticalChange,
                        Canvas.Margin.Right - e.HorizontalChange,
                        Canvas.Margin.Bottom - e.VerticalChange);
            }
        }

        //enable pivot's drag event.
        private void CanvasDragCompleted(object sender, DragCompletedGestureEventArgs e)
        {
            if (!e.Handled)
            {
                e.Handled = true;

                EnablePivotPage();
            }
        }

        /*=====================================================================
         * Gestures on Canvas, tap session.
         *===================================================================*/

        //di-highlight current control item, if applicable
        private void CanvasTap(object sender, Microsoft.Phone.Controls.GestureEventArgs e)
        {
            Updatehighlighted(null);
        }
        //reset canvas scale and position.
        private void GraphicViewDoubleTap(object sender, Microsoft.Phone.Controls.GestureEventArgs e)
        {
            CanvasTransformation.ScaleX = 1;
            CanvasTransformation.ScaleY = 1;

            Canvas.Margin = new Thickness(0, 0, 0, 0);
        }

        /*=====================================================================
         * Gestures on Control items, tap session.
         *===================================================================*/

        //show outline and four active dot.
        private void ControlAtomTap(object sender, Microsoft.Phone.Controls.GestureEventArgs e)
        {
            if (!e.Handled)
            {
                e.Handled = true;

                //show outline of active control item.
                ((ControlAtom)sender).Outline(true);

                //enable delete and linkTo button when control item highlighted
                Updatehighlighted((ControlAtom)sender);
            }
        }
        /*=====================================================================
         * Gestures on Control items, drag session.
         *===================================================================*/

        //disable parents' drag gestures
        private void ControlDragStarted(object sender, DragStartedGestureEventArgs e)
        {
            if (!e.Handled)
            {
                e.Handled = true;
                DisablePivotPage();

                //de-highlight other control items.
                Updatehighlighted(null);
            }
        }

        //drag control item around.
        private void ControlDragDelta(object sender, DragDeltaGestureEventArgs e)
        {
            if (!e.Handled)
            {
                e.Handled = true;

                Canvas.SetLeft((UIElement)sender, Canvas.GetLeft((UIElement)sender) + e.HorizontalChange);
                Canvas.SetTop((UIElement)sender, Canvas.GetTop((UIElement)sender) + e.VerticalChange);
            }
        }

        //enable pivot's drag event & make sure control item is within image.
        private void ControlDragCompleted(object sender, DragCompletedGestureEventArgs e)
        {
            if (!e.Handled)
            {
                e.Handled = true;

                CheckRangeWithinCanvas((UIElement)sender);
            }
            EnablePivotPage();
        }

        /*=====================================================================
         * UI misc.
         *===================================================================*/

        public void DisablePivotPage()
        {
            GraphicView.IsHitTestVisible = false;
        }

        public void EnablePivotPage()
        {
            GraphicView.IsHitTestVisible = true;
        }

        public void CheckRangeWithinCanvas(UIElement controlItem)
        {
            if (Canvas.GetLeft(controlItem) < 0)
                Canvas.SetLeft(controlItem, 0);
            else if (Canvas.GetLeft(controlItem) + ((ControlAtom)controlItem).Width > ControlContainer.Width)
                Canvas.SetLeft(controlItem, ControlContainer.Width - ((ControlAtom)controlItem).Width);

            if (Canvas.GetTop(controlItem) < 0)
                Canvas.SetTop(controlItem, 0);
            else if (Canvas.GetTop(controlItem) + ((ControlAtom)controlItem).Height > ControlContainer.Height)
                Canvas.SetTop(controlItem, ControlContainer.Height - ((ControlAtom)controlItem).Height);
        }
        public void ButtonTrigger()
        {
            if (highlighted == null)
            {
                delControlButton.IsEnabled = false;
                linkPageButton.IsEnabled = false;
            }
            else
            {
                delControlButton.IsEnabled = true;
                linkPageButton.IsEnabled = true;
            }
        }
        /*=====================================================================
         * Edit Control.
         *===================================================================*/

        //add control
        private void AddControl()
        {
            //initialize new control item.
            ControlAtom newItem = new ControlAtom(this);

            //UI layer stuff
            //TODO always throw exception here, don know why.
            try
            {
                ControlContainer.Children.Add(newItem);
            }
            catch (Exception e) {
                MessageBox.Show("Error: " + e.Message);
            }

            Canvas.SetLeft(newItem, 100);
            Canvas.SetTop(newItem, 200);

            //bind listeners
            BindControlItemListener(newItem);
            //database related
            controls.Add(newItem);
        }
        private void DelControl()
        {
            if (highlighted != null)
            {
                ControlContainer.Children.Remove(highlighted);
                controls.Remove(highlighted);

                MessageBox.Show(controls.Count + " controls left in current page");
                //database related remove
                //TODO 

                Updatehighlighted(null);
                ButtonTrigger();
            }
        }

        private void Updatehighlighted(ControlAtom newhighlighted)
        {
            highlighted = newhighlighted;

            foreach (ControlAtom control in controls)
                control.Outline(false);

            if (highlighted != null)
                highlighted.Outline(true);

            ButtonTrigger();
        }
        private void BindControlItemListener(ControlAtom newItem)
        {
            GestureListener listener = GestureService.GetGestureListener(newItem);
            listener.Tap += ControlAtomTap;
            listener.DragStarted += ControlDragStarted;
            listener.DragDelta += ControlDragDelta;
            listener.DragCompleted += ControlDragCompleted;
        }
    }
}